﻿using System.Collections.Generic;

namespace SwyishChess.Domain.Piece
{
    public class ChessPiecesModel
    {
        private const int CHESS_BOARD_ROW = 8;
        private const int CHESS_BOARD_COLUMN = 8;

        private const int BLACK_PLAYER = 2;
        private const int WHITE_PLAYER = 1;

        /// <summary>
        /// To keep track fo chess pieces location and status
        /// Multi dimensional array is used so the locaiton can be easily matched with chess board array
        /// </summary>
        public ChessPiece[,] ChessPieces { get; set; }

        /// <summary>
        /// Default constructor to instantiate the chess pieces array and call initialization methods
        /// </summary>
        public ChessPiecesModel()
        {
            ChessPieces = new ChessPiece[CHESS_BOARD_ROW, CHESS_BOARD_COLUMN];
            InitializeChessPieces();
        }

        /// <summary>
        /// Create and set the location of each chess pieces
        /// </summary>
        private void InitializeChessPieces()
        {
            int row = 0;
            int playerId = 0;

            for (row = 0; row < CHESS_BOARD_ROW; row++)
            {
                /* DECIDES WHAT COLOR THE CHESS WILL BE */
                if (row < 2)
                    playerId = 2;
                else if (row > 5)
                    playerId = 1;

                /* DECIDES WHAT TYPE OF CHESS PIECE IT WOULD BE */
                for (int column = 0; column < CHESS_BOARD_COLUMN; column++)
                {
                    if (row == 1 || row == 6)
                    {
                        ChessPieces[row, column] = new Pawn(playerId);
                    }
                    else if (row == 0 || row == 7)
                    {
                        if (column == 0 || column == 7)
                            ChessPieces[row, column] = new Rook(playerId);
                        else if (column == 1 || column == 6)
                            ChessPieces[row, column] = new Knight(playerId);
                        else if (column == 2 || column == 5)
                            ChessPieces[row, column] = new Bishop(playerId);
                        else if (column == 3)
                            ChessPieces[row, column] = new Queen(playerId);
                        else if (column == 4)
                            ChessPieces[row, column] = new King(playerId);
                    }
                    else
                        ChessPieces[row, column] = null;
                }
            }
        }

        /// <summary>
        /// Set the new location of chess piece if it has been moved
        /// </summary>
        /// <param name="row">Row location it is moving to</param>
        /// <param name="column">Column location it is moving to</param>
        /// <param name="cp">Chess piece that is being moved</param>
        /// <returns>Boolean value indicating whether it was successful or not</returns>
        public bool SetNewChessPieceLocation(int row, int column, ChessPiece cp)
        {
            /* REMOVES AN EXISTING OPPONENT CHESS PIECE IF THERE IS ONE */
            if (ChessPieces[row, column] != null)
            {
                if (ChessPieces[row, column].OwningPlayerId != cp.OwningPlayerId)
                {
                    ChessPieces[row, column] = null;
                }
                else
                {
                    return false;
                }
            }

            ChessPieces[row, column] = cp;

            return true;
        }

        /// <summary>
        /// Removes a ches piece from the game board
        /// </summary>
        /// <param name="cp">Chess piece to remove</param>
        public void RemoveChessPiece(ChessPiece cp)
        {
            for (int row = 0; row < CHESS_BOARD_ROW; row++)
            {
                for (int column = 0; column < CHESS_BOARD_COLUMN; column++)
                {
                    if (cp == ChessPieces[row, column])
                    {
                        ChessPieces[row, column] = null;
                    }
                }
            }
        }

        /// <summary>
        /// Returns the location of the chess piece
        /// </summary>
        /// <param name="cp">Chess piece to locate</param>
        /// <param name="row">chess piece's row location</param>
        /// <param name="column">chess piece's column location</param>
        public void GetLocationOfChessPiece(ChessPiece cp, out int row, out int column)
        {
            for (int rowIndex = 0; rowIndex < CHESS_BOARD_ROW; rowIndex++)
            {
                for (int columnIndex = 0; columnIndex < CHESS_BOARD_COLUMN; columnIndex++)
                {
                    if (cp == ChessPieces[rowIndex, columnIndex])
                    {
                        row = rowIndex;
                        column = columnIndex;
                        return;
                    }
                }
            }

            row = -1;
            column = -1;
        }

        /// <summary>
        /// Copies the chess pieces array
        /// </summary>
        /// <returns></returns>
        public ChessPiece[,] CreateCopiedChessPiecesArray()
        {
            ChessPiece[,] copy = new ChessPiece[8, 8];

            for (int row = 0; row < 8; row++)
            {
                for (int col = 0; col < 8; col++)
                {
                    if (ChessPieces[row, col] != null)
                    {
                        if (ChessPieces[row, col] is Pawn)
                        {
                            copy[row, col] = new Pawn(ChessPieces[row, col].OwningPlayerId);
                            ((Pawn)copy[row, col]).MoveCount = ((Pawn)ChessPieces[row, col]).MoveCount;
                        }
                        else if (ChessPieces[row, col] is King)
                        {
                            copy[row, col] = new King(ChessPieces[row, col].OwningPlayerId);
                            ((King)copy[row, col]).MoveCount = ((King)ChessPieces[row, col]).MoveCount;
                        }
                        else if (ChessPieces[row, col] is Knight)
                        {
                            copy[row, col] = new Knight(ChessPieces[row, col].OwningPlayerId);
                        }
                        else if (ChessPieces[row, col] is Bishop)
                        {
                            copy[row, col] = new Bishop(ChessPieces[row, col].OwningPlayerId);
                        }
                        else if (ChessPieces[row, col] is Rook)
                        {
                            copy[row, col] = new Rook(ChessPieces[row, col].OwningPlayerId);
                            ((Rook)copy[row, col]).MoveCount = ((Rook)ChessPieces[row, col]).MoveCount;
                        }
                        else if (ChessPieces[row, col] is Queen)
                        {
                            copy[row, col] = new Queen(ChessPieces[row, col].OwningPlayerId);
                        }

                    }
                }
            }

            return copy;
        }

    }
}
